<template>
  <view>
    <!-- 自定义导航栏 -->
    <u-navbar autoBack placeholder title="聊天记录"></u-navbar>
    <!-- 聊天内容列表 -->
    <view
      class="message-list"
      :style="{ minHeight: `calc(100vh - 44px - ${statusBarHeight})` }"
    >
      <template v-if="isCompleted">
        <!-- 没有更多了 -->
        <u-loadmore
          style="margin-bottom: 40rpx"
          v-if="isCompleted"
          status="nomore"
        ></u-loadmore>
        <!-- 描述症状内容 -->
        <view class="message-item reverse">
          <u-avatar
            src=""
            size="80rpx"
            default-url="/static/avatar.png"
          ></u-avatar>
          <view class="item-right">
            <!-- <view class="name">
							{{ orderdetail.name + " 医生" }}
						</view> -->
            <view class="time">{{ orderInfo.createDate || "" }}</view>
            <view class="content">
              <view class="miaoshu-zhengzhuang">
                <view class="miaoshu-item">
                  <text style="color: #666">病情描述：</text>
                  {{ orderInfo.depict || "" }}
                </view>
                <!-- <view class="miaoshu-item">
									<text style="color: #666;">患病时长：</text>
									{{ orderInfo.duration || "" }}
								</view> -->
                <view class="miaoshu-item">
                  <text style="color: #666">医院检查：</text>
                  {{ orderInfo.examine || "" }}
                </view>
                <view class="miaoshu-img" v-if="orderInfo.depictImage">
                  <image
                    @click="handlePreviewImage(baseurl + item)"
                    class="img"
                    :key="index"
                    v-for="(item, index) in orderInfo.depictImage"
                    :src="baseurl + item"
                    mode="aspectFill"
                  ></image>
                </view>
                <!-- <view class="miaoshu-item">
									<text style="color: #666;">用药情况：</text>
									{{ orderInfo.medication || "" }}
								</view> -->
                <view class="miaoshu-img" v-if="orderInfo.imageUrls">
                  <image
                    @click="handlePreviewImage(baseurl + item)"
                    class="img"
                    :key="index"
                    v-for="(item, index) in orderInfo.imageUrls"
                    :src="baseurl + item"
                    mode="aspectFill"
                  ></image>
                </view>
              </view>
            </view>
          </view>
        </view>
      </template>
      <template v-if="messageList.length > 0">
        <view
          v-for="(item, index) in messageList"
          :key="item.MsgKey"
          class="message-item"
          :class="{ reverse: item.From_Account === userId }"
        >
          <u-avatar
            :src="
              item.From_Account === userId
                ? ''
                : baseurl + orderdetail.headImage
            "
            size="80rpx"
            default-url="../../static/avatar.png"
          ></u-avatar>
          <view class="item-right">
            <view class="name" v-if="item.From_Account !== userId">
              {{ orderdetail.name + " 医生" }}
            </view>
            <view class="time">{{ item.MsgTime | filterTime }}</view>
            <!-- 图片内容 -->
            <view
              v-if="item.MsgContent && item.MsgContent.Data === 'image'"
              @click="
                handlePreviewImage(item.MsgContent && item.MsgContent.Desc)
              "
            >
              <u-image
                width="300rpx"
                height="300rpx"
                radius="16rpx"
                :fade="false"
                :src="(item.MsgContent && item.MsgContent.Desc) | filterUrl"
                mode="aspectFill"
              ></u-image>
            </view>
            <!-- 视频内容 -->
            <view
              v-else-if="item.MsgContent && item.MsgContent.Data === 'video'"
              class="content-video"
              @click="handleVideoPlay(item.MsgContent.Desc)"
            >
              <image
                class="video-bg"
                src="/static/message/video-bg.png"
                mode="aspectFill"
              ></image>
              <image
                class="video-play"
                src="/static/message/video-play.png"
                mode=""
              ></image>
              <text class="video-time">
                {{
                  (item.MsgContent && item.MsgContent.Desc) | filterVideoTime
                }}
              </text>
            </view>
            <!-- 问诊将在查看病例报告24小时后结束 -->
            <view
              v-else-if="
                item.MsgContent &&
                item.MsgContent.Data === 'createDiseaseCaseCountDown'
              "
            ></view>
            <!-- 带边距的内容 -->
            <view class="content-box" v-else>
              <view class="content-wrap">
                <view class="content">
                  <!-- 文本内容 -->
                  <text class="text" v-if="item.MsgType === 'TIMTextElem'">
                    {{ item.MsgContent && item.MsgContent.Text }}
                  </text>
                  <!-- 病历报告已生成 -->
                  <view
                    v-else-if="
                      item.MsgContent &&
                      item.MsgContent.Data === 'createDiseaseCase'
                    "
                    class="case-report"
                    @click="goCaseReport"
                  >
                    病历报告已生成
                  </view>
                  <!-- 发送上门时间 -->
                  <view
                    class="shangmen-time"
                    v-else-if="
                      item.MsgContent &&
                      item.MsgContent.Data === 'sendVisitDate'
                    "
                  >
                    <view class="shangmen-one">
                      {{ item.MsgContent && item.MsgContent.Desc }}上门
                    </view>
                    <view class="shangmen-two">等待患者同意</view>
                  </view>
                  <!-- 患者拒绝上门时间 -->
                  <view
                    class="shangmen-time"
                    v-else-if="
                      item.MsgContent &&
                      item.MsgContent.Data === 'refuseVisitDate'
                    "
                  >
                    <view class="shangmen-one">
                      {{ item.MsgContent && item.MsgContent.Desc }}上门
                    </view>
                    <view class="shangmen-two">已拒绝</view>
                  </view>
                  <!-- 患者同意上门时间 -->
                  <view
                    class="shangmen-time"
                    v-else-if="
                      item.MsgContent &&
                      item.MsgContent.Data === 'confirmVisitDate'
                    "
                  >
                    <view class="shangmen-one">
                      {{ item.MsgContent && item.MsgContent.Desc }}上门
                    </view>
                    <view class="shangmen-two">已同意</view>
                  </view>
                  <!-- 辅料清单 -->
                  <view
                    class="shangmen-time"
                    v-else-if="
                      item.MsgContent &&
                      item.MsgContent.Data === 'materielProduct'
                    "
                  >
                    <view
                      class="shangmen-one"
                      style="color: #3fa3fa"
                      @click="goMaterialsList(item.MsgContent.Ext)"
                    >
                      辅料清单，点击查看
                    </view>
                    <view class="shangmen-two">
                      {{
                        (item.MsgContent && item.MsgContent.Desc) === "1"
                          ? "未付款"
                          : "已付款"
                      }}
                    </view>
                  </view>
                  <!-- 结束问诊 -->
                  <view
                    class="shangmen-time"
                    v-else-if="
                      item.MsgContent && item.MsgContent.Data === 'orderOver'
                    "
                  >
                    <view class="shangmen-one" style="color: #3fa3fa">
                      治疗已完成
                    </view>
                    <view class="shangmen-two">已确认</view>
                  </view>

                  <!-- 语音内容 -->
                  <view
                    class="audio-box"
                    v-else-if="
                      item.MsgContent && item.MsgContent.Data === 'audio'
                    "
                    @click="hanlePlayRecord(item)"
                  >
                    <image
                      class="audio-img"
                      :src="
                        item.audioPlay
                          ? '/static/message/icon-pause.png'
                          : '/static/message/icon-play.png'
                      "
                      mode=""
                    ></image>
                    <image
                      class="audio-bolang"
                      src="/static/message/icon-bolang.png"
                      mode=""
                    ></image>
                    <text class="audio-text">
                      {{
                        (item.MsgContent && item.MsgContent.Desc)
                          | filterAudioTime
                      }}
                    </text>
                  </view>
                </view>
                <!-- 转文字按钮 -->
                <view
                  v-if="
                    item.MsgContent &&
                    item.MsgContent.Data === 'audio' &&
                    !item.isAudioToText
                  "
                  class="change-text-btn"
                  @click="handleAudioToText(item)"
                >
                  转文字
                </view>
              </view>
              <!-- 语音转文字内容 -->
              <view
                class="content-wrap2"
                v-if="
                  item.MsgContent &&
                  item.MsgContent.Data === 'audio' &&
                  item.isAudioToText
                "
              >
                <view class="change-text-content">{{ item.audioText }}</view>
              </view>
            </view>
          </view>
        </view>
      </template>
    </view>
    <!-- 视频 -->
    <video
      v-if="!!videoUrl"
      id="my-video"
      :src="videoUrl"
      controls
      @fullscreenchange="handleVideoFullScreenChange"
    ></video>
  </view>
</template>

<script>
import {
  getChatRecord,
  getOrderDepict,
  recordingRecognition,
} from '../../api/index.js'
export default {
  data() {
    return {
      query: {
        pageNumber: 0,
        pageSize: 15,
      },
      messageList: [], // 消息列表
      orderNumber: "", // 订单号
      patientName: "", // 患者名称
      timer: null, // 定时器
      isCompleted: false, // 是否加载完成
      requestCount: 0, // 请求次数
      scrollHeight: 0, // 滚动高度
      orderInfo: {}, // 订单描述内容
      userId: "",
      orderdetail: {}, //订单信息
      baseurl: "",
      innerAudioContext: null, //语音播放实例
      videoUrl: "", // 视频播放地址
      videoContext: null, // 视频上下文
    };
  },
  filters: {
    filterTime(time) {
      return uni.$dayjs(time * 1000).format("YYYY-MM-DD HH:mm:ss");
    },
    filterAudioTime(description) {
      const time = Number(description.split("|")[1]) || 0;
      if (time < 60) {
        return `${time % 60}”`;
      } else {
        return `${Math.floor(time / 60)}’${time % 60}”`;
      }
    },
    // 过滤视频时间
    filterVideoTime(description) {
      if (!description) return "0:00";
      const videoTime = Number(description.split("|")[1]) || 0;
      // 超过60秒的 按照几分几秒显示
      if (videoTime >= 60)
        return `${Math.floor(videoTime / 60)}:${(videoTime % 60)
          .toString()
          .padStart(2, "0")}`;
      return `0:${videoTime.toString().padStart(2, "0")}`;
    },
  },
  computed: {
    statusBarHeight() {
      const { statusBarHeight } = uni.getSystemInfoSync() || {};
      return (statusBarHeight || 0) + "px";
    },
    doctorAvatar() {
      return this.baseurl + uni.getStorageSync("headImage");
    },
  },
  onLoad(options) {
    // if (options.orderNumber && options.patientName) {
    // 	this.orderNumber = options.orderNumber;
    // 	this.patientName = options.patientName || "";
    // 	this._getOrderDepict();
    // 	this._getChatRecord();
    // }
    this.baseurl = this.$store.state.chronic.baseUrl;
    this.userId = uni.getStorageSync("userId");
    let orderdetail = JSON.parse(decodeURIComponent(options.orderdetail));
    if (orderdetail.orderNumber) {
      this.orderdetail = orderdetail;
      console.log("orderdetail", this.orderdetail.orderNumber);
      this._getOrderDepict();
      this._getChatRecord();
    }
  },
  onUnload() {
    // 清除定时器
    this.timer && clearTimeout(this.timer);
    this.timer = null;
    // 销毁语音播放实例
    this.innerAudioContext && this.innerAudioContext.destroy();
  },
  onPageScroll(e) {
    // 加载完毕聊天记录就不用执行后面的了
    if (this.isCompleted) return;
    this.$u.debounce(() => {
      const scrollTop = e.scrollTop;
      if (scrollTop <= 50) {
        console.log("滚到顶部了");
        this._getChatRecord();
      }
    }, 200);
  },
  methods: {
    // 播放视频
    handleVideoPlay(description) {
      this.videoUrl = this.baseurl + description.split("|")[0];
      this.$nextTick(() => {
        this.videoContext = uni.createVideoContext("my-video");
        this.videoContext.requestFullScreen({ direction: 0 });
        this.videoContext.play();
      });
    },
    // 视频进入退出全屏的事件
    handleVideoFullScreenChange(e) {
      console.log("视频进入或者退出全屏", e.detail);
      const { fullScreen } = e.detail;
      if (!fullScreen) {
        this.videoContext.pause();
        this.videoUrl = "";
        this.videoContext = null;
      }
    },
    // 语音转文字
    handleAudioToText(item) {
      uni.showLoading({
        title: "努力转换中...",
        mask: true,
        duration: 60000,
      });
      recordingRecognition({
        fileUrl: item.MsgContent && item.MsgContent.Desc.split("|")[0],
      }).then((res) => {
        uni.hideLoading();
        if (res.code == 200) {
          console.log("语音转文字", res.data);
          this.$set(item, "isAudioToText", true);
          this.$set(item, "audioText", res.data || "");
        }
      });
    },
    // 根据订单号获取聊天记录
    async _getChatRecord() {
      if (this.isCompleted) return;
      this.query.pageNumber += 1;
      if (!this.orderdetail.orderNumber) return;
      const res = await getChatRecord({
        orderNumber: this.orderdetail.orderNumber,
        ...this.query,
      }).catch((err) => {
        return Promise.reject(err);
      });
      console.log("聊天记录数据", res.data);
      let { records, total } = res.data || {};
      records = records || [];
      total = total || 0;
      records = records
        .map((item) => {
          if (item.recordJson) {
            item.recordJson = JSON.parse(item.recordJson);
          }
          return {
            orderNumber: item.orderNumber,
            MsgKey: item.recordJson.MsgKey,
            To_Account: item.recordJson.To_Account,
            From_Account: item.recordJson.From_Account,
            MsgContent: item.recordJson.MsgBody[0].MsgContent || {},
            MsgType: item.recordJson.MsgBody[0].MsgType || "",
            MsgTime: item.recordJson.MsgTime || "",
            CloudCustomData: item.recordJson.CloudCustomData || "",
          };
        })
        .filter(
          (item) =>
            item.CloudCustomData === this.orderdetail.orderNumber ||
            (item.MsgContent && item.MsgContent.Ext) ===
            this.orderdetail.orderNumber
        );
      records.forEach((item) => {
        item.audioPlay = false;
        item.isAudioToText = false;
        item.audioText = "";
      });
      // 对聊天记录进行排序
      records.sort((a, b) => a.MsgTime - b.MsgTime);
      console.log("聊天记录处理后数据", records);
      // 只有第一次进来聊天页面触发初始化滚到底部
      if (this.requestCount === 0) {
        this.messageList.unshift(...records);
        this.isCompleted = this.messageList.length >= total;
        if (
          !this.isCompleted &&
          this.messageList.length < this.query.pageSize
        ) {
          this._getChatRecord();
        } else {
          this.requestCount += 1;
          // 延迟200ms，等待渲染完毕
          this.timer && clearTimeout(this.timer);
          this.timer = setTimeout(() => {
            this.$nextTick(async () => {
              // 初始化记录滚动区域高度
              const container = await this.$utils.getRect(".message-list");
              console.log("获取到的节点信息", container);
              this.scrollHeight = container.height;
              this.handleScrollToBottom();
            });
          }, 200);
        }
        return;
      }
      this.messageList.unshift(...records);
      this.isCompleted = this.messageList.length >= total;
      this.$nextTick(() => {
        // 延迟100ms，有时候居然连文字都渲染不完毕
        this.timer && clearTimeout(this.timer);
        this.timer = setTimeout(async () => {
          // 定位聊天记录滚动条位置
          const container = await this.$utils.getRect(".message-list");
          console.log("获取到的节点信息", container);
          uni.pageScrollTo({
            scrollTop: container.height - this.scrollHeight,
            duration: 0,
            success: () => {
              this.scrollHeight = container.height;
            },
          });
        }, 100);
      });
    },
    // 获取订单描述内容
    _getOrderDepict() {
      getOrderDepict({
        orderNumber: this.orderdetail.orderNumber,
      }).then((res) => {
        if (res.code == 200) {
          console.log("获取订单描述内容", res.data);
          const data = res.data || {};
          if (data.imageUrls) {
            data.imageUrls = data.imageUrls.split(",");
          }
          this.orderInfo = data;
        }
      });
    },
    // 聊天内容滚动到底部
    handleScrollToBottom(time = 0) {
      if (time > 0) {
        this.timer && clearTimeout(this.timer);
        this.timer = setTimeout(() => {
          this.$nextTick(() => {
            uni.pageScrollTo({
              duration: 0,
              scrollTop: 99999999,
            });
          });
        }, time);
      } else {
        this.$nextTick(() => {
          uni.pageScrollTo({
            duration: 0,
            scrollTop: 99999999,
          });
        });
      }
    },
    // 预览图片
    handlePreviewImage(url) {
      this.$utils.previewImage(url);
    },
    // 查看病历报告
    goCaseReport() {
      uni.navigateTo({
        url:
          "/pages/index/medical-report/medical-report?orderNumber=" +
          this.orderdetail.orderNumber,
      });
    },
    // 跳转辅料清单
    goMaterialsList() {
      uni.navigateTo({
        url:
          "/pages/index/accessories/accessories?orderNumber=" +
          this.orderdetail.orderNumber,
      });
    },

    // 播放语音
    hanlePlayRecord(item) {
      // 正在播放中，点击就停止播放
      if (item.audioPlay) {
        this.innerAudioContext && this.innerAudioContext.stop();
        // 设置语音未播放状态
        this.$set(item, "audioPlay", false);
        return;
      }
      // 将所有语音重置为未播放状态
      this.messageList.forEach((data) => {
        this.$set(data, "audioPlay", false);
      });
      const description = item.MsgContent && item.MsgContent.Desc;
      const audioUrl = this.baseurl + description.split("|")[0];
      // 语音实例也对应销毁
      this.innerAudioContext && this.innerAudioContext.destroy();
      this.innerAudioContext = uni.createInnerAudioContext();
      this.innerAudioContext.src = audioUrl;
      this.innerAudioContext.play();
      this.innerAudioContext.onPlay(() => {
        // 设置语音为播放状态
        this.$set(item, "audioPlay", true);
        console.log("语音开始播放");
      });
      this.innerAudioContext.onEnded(() => {
        // 设置语音为未播放状态
        this.$set(item, "audioPlay", false);
        console.log("语音播放完毕");
      });
      this.innerAudioContext.onError((res) => {
        this.$utils.showToast("语音播放失败");
        console.log("语音播放出错", res.errMsg);
        console.log("语音播放出错code", res.errCode);
      });
    },
  },
};
</script>
<style>
view,
text {
  box-sizing: border-box;
}
</style>
<style lang="scss" scoped>
.message-list {
  width: 100%;
  background-color: #f7f7f7;
  padding: 40rpx;
  overflow-y: auto;
}

.message-item {
  width: 100%;
  display: flex;
  flex-direction: row;
  margin-bottom: 40rpx;
  &:last-child {
    margin-bottom: 0;
  }
  .revoked-message-box {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    .revoked-message {
      padding: 0 16rpx;
      height: 52rpx;
      background-color: #fff;
      font-size: 20rpx;
      color: #666;
      display: flex;
      align-items: center;
      justify-content: center;
    }
  }

  .item-right {
    margin-left: 28rpx;
    width: 0;
    flex: 1;
    display: flex;
    flex-direction: column;
  }
  .name {
    font-size: 28rpx;
    margin-bottom: 8rpx;
  }
  .time {
    font-size: 24rpx;
    color: #999;
    margin-bottom: 20rpx;
  }
  .content-box {
    width: auto;
    .content-wrap {
      display: flex;
      align-items: center;
    }
    .content-wrap2 {
      display: flex;
      align-items: center;
    }
  }
  // 带边距的内容
  .content {
    width: max-content;
    max-width: 448rpx;
    padding: 24rpx;
    background-color: #fff;
    border-radius: 16rpx;
    font-size: 0;
    // 文本内容
    .text {
      display: inline-block;
      font-size: 28rpx;
      text-align: justify;
      word-break: break-all;
    }
    // 描述症状内容
    .miaoshu-zhengzhuang {
      width: 100%;
      .miaoshu-item {
        font-size: 28rpx;
        margin-bottom: 8rpx;
      }
      .miaoshu-img {
        width: 100%;
        margin-top: 20rpx;
        display: flex;
        flex-wrap: wrap;
        font-size: 0;
        .img {
          width: 120rpx;
          height: 120rpx;
          border-radius: 8rpx;
          margin-right: 20rpx;
          margin-bottom: 20rpx;
          &:nth-child(3n) {
            margin-right: 0;
          }
        }
      }
    }
    // 病历报告已生成
    .case-report {
      font-size: 28rpx;
      color: #3fa3fa;
    }
    // 上门时间
    .shangmen-time {
      width: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      .shangmen-one {
        min-width: 340rpx;
        height: 64rpx;
        background-color: rgba(#e0f0fe, 0.3);
        border-radius: 8rpx;
        margin-bottom: 20rpx;
        font-size: 28rpx;
        color: #333;
        display: flex;
        align-items: center;
        justify-content: center;
      }
      .shangmen-two {
        min-width: 206rpx;
        padding: 0 68rpx;
        height: 64rpx;
        background-color: rgba(#e0f0fe, 0.3);
        border-radius: 8rpx;
        margin-bottom: 20rpx;
        font-size: 28rpx;
        color: #333;
        display: flex;
        align-items: center;
        justify-content: center;
      }
    }
    // 语音播放
    .audio-box {
      display: flex;
      align-items: center;
      .audio-img {
        width: 32rpx;
        height: 32rpx;
      }
      .audio-bolang {
        width: 76rpx;
        height: 34rpx;
        margin: 0 8rpx;
      }
      .audio-text {
        font-size: 24rpx;
      }
    }
  }
  // 语音转文字内容
  .change-text-content {
    width: max-content;
    max-width: 448rpx;
    padding: 24rpx;
    background-color: #fff;
    border-radius: 16rpx;
    color: #333;
    font-size: 28rpx;
    text-align: justify;
    margin-top: 12rpx;
  }

  // 视频内容
  .content-video {
    width: 172rpx;
    height: 284rpx;
    border-radius: 16rpx;
    overflow: hidden;
    position: relative;
    .video-bg {
      width: 100%;
      height: 100%;
    }
    .video-play {
      width: 60rpx;
      height: 60rpx;
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      margin: auto;
      z-index: 5;
    }
    .video-time {
      font-size: 20rpx;
      color: #fff;
      position: absolute;
      right: 8rpx;
      bottom: 8rpx;
      z-index: 10;
    }
  }
  // 转文字按钮
  .change-text-btn {
    width: 92rpx;
    height: 40rpx;
    background: #ffffff;
    border-radius: 20rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20rpx;
    color: #666;
    margin-left: 20rpx;
  }
  // 反转的样式
  &.reverse {
    flex-direction: row-reverse;
    .item-right {
      margin-left: 0;
      margin-right: 28rpx;
      align-items: flex-end;
    }
    .content {
      background-color: #e0f0fe;
      .shangmen-one,
      .shangmen-two {
        background-color: #fff;
      }
    }
    .content-wrap {
      flex-direction: row-reverse;
    }
    .content-wrap2 {
      flex-direction: row-reverse;
    }
    .change-text-btn {
      margin-left: 0;
      margin-right: 20rpx;
    }
  }
}
.lackcon {
  position: relative;
  left: -5vw;
}
</style>
